package com.kriss.crm.base;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class BaseDaoImpl extends HibernateDaoSupport implements IBaseDao {

	public Long count(final String hql, final Object... values)
			throws Exception {
		return this.getHibernateTemplate().execute(
				new HibernateCallback<Long>() {
					public Long doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						if (values != null) {
							for (int i = 0; i < values.length; i++) {
								query.setParameter(i, values[i]);
							}
						}
						return (Long) query.uniqueResult();
					}
				});
	}

	public <T> void delete(T t) throws Exception {
		this.getHibernateTemplate().delete(t);
	}

	public <T> List<T> findAll(String hql, Object... values) throws Exception {
		return this.getHibernateTemplate().find(hql, values);
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> findAll(final String hql, final int firstResult,
			final int maxResult, final Object... values) throws Exception {
		return this.getHibernateTemplate().executeFind(
				new HibernateCallback<List<T>>() {
					public List<T> doInHibernate(Session session)
							throws HibernateException, SQLException {

						Query query = session.createQuery(hql);
						if (values != null) {
							for (int i = 0; i < values.length; i++) {
								query.setParameter(i, values[i]);
							}
						}

						query.setFirstResult(firstResult);
						query.setMaxResults(maxResult);
						return query.list();
					}
				});

	}

	public <T> T get(Class<T> cls, Serializable ID) throws Exception {
		return this.getHibernateTemplate().get(cls, ID);
	}

	public <T> void save(T t) throws Exception {
		this.getHibernateTemplate().save(t);
	}

	public <T> void update(T t) throws Exception {
		this.getHibernateTemplate().update(t);
	}

	public <T> T findOneByHql(final String hql, final Object... values)
			throws Exception {
		return 	this.getHibernateTemplate().execute(new HibernateCallback<T>() {
			public T doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query query = session.createQuery(hql);

				if (values != null) {
					for (int i = 0; i < values.length; i++) {
						query.setParameter(i, values[i]);
					}
				}
				return (T) query.uniqueResult();
			}
		});
	}

}
